<template>
  <div class="widget-item-container">
    <a-form-item
      v-if="element && element.type !== 'button'"
      :key="element.key"
      :class="{
        active: selectWidget?.key === element.key,
        'widget-view': true,
        '!p-0': element.type == 'tab',
      }"
      :label="
        !noHaveTitle.includes(element.type) && element.options?.showLabel ? element.label : ''
      "
      :rules="element.options.rules"
      :required="element.options.required"
    >
      <template v-if="element.type === 'input'">
        <a-input
          :size="config.size"
          :value="element.options.defaultValue"
          :placeholder="element.options.placeholder"
          :maxlength="parseInt(element.options.maxlength)"
          :addonBefore="element.options.addonBefore"
          :addonAfter="element.options.addonAfter"
          :allowClear="element.options.allowClear"
          :disabled="element.options.disabled"
          :readonly="element.options.readonly"
        >
          <template #prefix v-if="element.options.prefix">
            <Icon :icon="element.options.prefix" />
          </template>
          <template #suffix v-if="element.options.suffix">
            <Icon :icon="element.options.suffix" />
          </template>
        </a-input>
      </template>

      <template v-if="element.type === 'password'">
        <a-input-password
          :size="config.size"
          :value="element.options.defaultValue"
          :placeholder="element.options.placeholder"
          :maxlength="element.options.maxlength"
          :addonBefore="element.options.addonBefore"
          :addonAfter="element.options.addonAfter"
          :allowClear="element.options.allowClear"
          :disabled="element.options.disabled"
          :readonly="element.options.readonly"
          :visibilityToggle="element.options.visibilityToggle"
        >
          <template #prefix v-if="element.options.prefix">
            <Icon :icon="element.options.prefix" />
          </template>
        </a-input-password>
      </template>

      <template v-if="element.type === 'textarea' || element.type === 'opinion'">
        <a-textarea
          style="resize: none"
          :size="config.size"
          :rows="element.options.rows"
          :value="element.options.defaultValue"
          :placeholder="element.options.placeholder"
          :maxlength="element.options.maxlength"
          :showCount="element.options.showCount"
          :allowClear="element.options.allowClear"
          :disabled="element.options.disabled"
          :readonly="element.options.readonly || element.type === 'opinion'"
          :autoSize="element.options.autoSize"
        />
      </template>

      <template v-if="element.type === 'area'">
        <SelectArea
          :size="config.size"
          :placeholder="element.options.placeholder"
          :allowClear="element.options.allowClear"
          :disabled="element.options.disabled"
          :readonly="element.options.readonly"
        />
      </template>
      <template v-if="element.type === 'auto-code'">
        <AutoCodeRule
          :size="config.size"
          :placeholder="element.options.placeholder"
          :addonBefore="element.options.addonBefore"
          :addonAfter="element.options.addonAfter"
          :prefix="element.options.prefix"
          :suffix="element.options.suffix"
          :autoCodeRule="element.options.autoCodeRule"
        />
      </template>

      <template v-if="element.type === 'number'">
        <a-input-number
          :size="config.size"
          :value="element.options.defaultValue"
          :max="element.options.max"
          :min="element.options.min"
          :step="element.options.step"
          :disabled="element.options.disabled"
          :readonly="element.options.readonly"
          :maxlength="element.options.maxlength"
          style="width: 100%"
        />
      </template>

      <template v-if="element.type === 'radio'">
        <ApiRadioGroup
          :size="config.size"
          :value="element.options.defaultSelect"
          :disabled="element.options.disabled"
          :optionType="element.options.optionType"
          :params="element.options.params"
          :labelField="element.options.labelField"
          :valueField="element.options.valueField"
          :datasourceType="element.options.datasourceType"
          :staticOptions="element.options.staticOptions"
          :defaultSelect="element.options.defaultSelect"
          :apiConfig="element.options.apiConfig"
          :class="[element.options.optionType === 'button' ? 'radio-button' : 'radio-default']"
        />
      </template>

      <template v-if="element.type === 'checkbox'">
        <ApiCheckboxGroup
          :size="config.size"
          :value="element.options.defaultSelect"
          :disabled="element.options.disabled"
          :params="element.options.params"
          :labelField="element.options.labelField"
          :valueField="element.options.valueField"
          :datasourceType="element.options.datasourceType"
          :staticOptions="element.options.staticOptions"
          :defaultSelect="element.options.defaultSelect"
          :apiConfig="element.options.apiConfig"
        />
      </template>

      <template v-if="element.type === 'time'">
        <TimePicker
          :size="config.size"
          :value="element.options.defaultValue"
          :placeholder="element.options.placeholder"
          :allowClear="element.options.allowClear"
          :format="element.options.format"
          :disabled="element.options.disabled"
          style="width: 100%"
        />
      </template>

      <template v-if="element.type === 'date'">
        <XjrDatePicker
          :size="config.size"
          :value="element.options.defaultValue"
          :placeholder="element.options.placeholder"
          :allowClear="element.options.allowClear"
          :format="element.options.format"
          :disabled="element.options.disabled"
          style="width: 100%"
        />
      </template>

      <template v-if="element.type === 'date-range'">
        <a-range-picker
          :size="config.size"
          :format="element.options.format"
          :show-time="element.options.showTime"
          :placeholder="[element.options.startTimePlaceholder, element.options.endTimePlaceholder]"
          :allowClear="element.options.allowClear"
          :disabled="element.options.disabled"
          style="width: 100%"
        />
      </template>

      <template v-if="element.type === 'time-range'">
        <a-time-range-picker
          :size="config.size"
          :format="element.options.format"
          :show-time="element.options.showTime"
          :placeholder="[element.options.startTimePlaceholder, element.options.endTimePlaceholder]"
          :allowClear="element.options.allowClear"
          :disabled="element.options.disabled"
          style="width: 100%"
        />
      </template>

      <template v-if="element.type === 'rate'">
        <a-rate
          :value="element.options.defaultValue"
          :count="element.options.count"
          :allowHalf="element.options.allowHalf"
          :allowClear="element.options.allowClear"
          :disabled="element.options.disabled"
        />
      </template>

      <template v-if="element.type === 'select'">
        <ApiSelect
          :size="config.size"
          :mode="element.options.mode"
          :value="element.options.defaultSelect"
          :placeholder="element.options.placeholder"
          :filter-option="handleFilterOption"
          :allowClear="element.options.clearable"
          :showSearch="element.options.showSearch"
          :disabled="element.options.disabled"
          :readonly="element.options.readonly"
          :params="element.options.params"
          :labelField="element.options.labelField"
          :valueField="element.options.valueField"
          :datasourceType="element.options.datasourceType"
          :staticOptions="element.options.staticOptions"
          :defaultSelect="element.options.defaultSelect"
          :apiConfig="element.options.apiConfig"
        />
      </template>

      <template v-if="element.type === 'switch'">
        <XjrSwitch
          :size="config.size"
          :checked="element.options.defaultValue"
          :checkedChildren="element.options.checkedChildren"
          :unCheckedChildren="element.options.unCheckedChildren"
          :disabled="element.options.disabled"
          :checkedColor="element.options.checkedColor"
          :unCheckedColor="element.options.unCheckedColor"
        />
      </template>

      <template v-if="element.type === 'slider'">
        <a-slider
          :value="element.options.defaultValue"
          :min="element.options.min"
          :max="element.options.max"
          :step="element.options.step"
          :reverse="element.options.reverse"
          :disabled="element.options.disabled"
        />
      </template>

      <template v-if="element.type == 'text'">
        <span>{{ element.options.defaultValue }}</span>
      </template>

      <template v-if="element.type === 'multiple-popup' || element.type === 'associate-popup'">
        <a-input
          :readonly="element.options.readonly"
          :value="element.options.defaultValue"
          :size="config.size"
          :placeholder="element.options.placeholder"
          :maxlength="parseInt(element.options.maxlength)"
          :addonBefore="element.options.addonBefore"
          :addonAfter="element.options.addonAfter"
          :allowClear="element.options.allowClear"
          :disabled="element.options.disabled"
        />
      </template>

      <template v-if="element.type === 'associate-select'">
        <AssociateSelect
          :size="config.size"
          :mode="element.options.mode"
          :value="element.options.defaultSelect"
          :placeholder="element.options.placeholder"
          :filter-option="handleFilterOption"
          :showSearch="element.options.showSearch"
          :disabled="element.options.disabled"
          :labelField="element.options.labelField"
          :valueField="element.options.valueField"
          :datasourceType="element.options.datasourceType"
          :params="element.options.params"
          :staticOptions="element.options.staticOptions"
          :defaultSelect="element.options.defaultSelect"
          :apiConfig="element.options.apiConfig"
        />
      </template>

      <template v-if="element.type === 'picker-color'">
        <ColorPicker :value="element.options.defaultValue" :disabled="element.options.disabled" />
      </template>

      <!-- <template v-if="element.type === 'button'">
        <a-button
          type="primary"
          :size="config.size"
          :disabled="element.options.disabled"
          :style="{
            height: element.options.buttonHeight ? element.options.buttonHeight + 'px' : '',
            width: element.options.buttonWidth ? element.options.buttonWidth + 'px' : '',
          }"
        >
          <Icon :icon="element.options.prefix" />
          {{ element.options.name }}
          <Icon :icon="element.options.suffix" />
        </a-button>
      </template> -->

      <template v-if="element.type == 'image'">
        <a-image
          :width="200"
          :src="element.options.defaultValue"
          fallback=""
        />
      </template>

      <template v-if="element.type == 'divider'">
        <a-divider
          :orientation="element.options.orientation"
          :style="{
            marginTop: element.options.marginTop + 'px',
            marginBottom: element.options.marginBottom + 'px',
          }"
        >
          {{ element.options.defaultValue }}
        </a-divider>
      </template>

      <template v-if="element.type === 'upload'">
        <a-upload
          :name="element.options.name"
          :accept="element.options.accept"
          :action="`${getAppEnvConfig().VITE_GLOB_API_URL}${
            getAppEnvConfig().VITE_GLOB_UPLOAD_URL
          }`"
          :headers="{ Authorization: `Bearer ${getToken()}` }"
          :file-list="element.options.defaultValue"
          :multiple="element.options.multiple"
          :disabled="element.options.disabled"
        >
          <a-button
            style="width: 108px; height: 108px"
            v-if="element.options.listType == 'picture-card'"
            ><plus-outlined style="font-size: 60px; color: #eee"
          /></a-button>
          <a-button type="primary" v-else>
            {{ t('选择文件') }}
          </a-button>
        </a-upload>
      </template>

      <template v-if="element.type === 'richtext-editor'">
        <RichTextEditor
          :disabled="element.options.disabled"
          :readonly="element.options.readonly"
          :value="element.options.defaultValue"
          :width="element.options.width"
        />
      </template>

      <template v-if="element.type === 'cascader'">
        <ApiCascader
          :size="config.size"
          :placeholder="element.options.placeholder"
          :separator="element.options.separator"
          :showFormat="element.options.showFormat"
          :selectedConfig="element.options.selectedConfig"
          :apiConfig="element.options.apiConfig"
          :allowClear="element.options.allowClear"
          :disabled="element.options.disabled"
        />
      </template>
      <template v-if="element.type === 'title'">
        <a-row
          v-if="element.key"
          :key="element.key"
          :class="{ active: selectWidget?.key === element.key }"
        >
          <a-col :span="24">
            <h2
              :align="element.options.align"
              :style="{
                fontSize: element.options.fontSize + 'px',
                color: element.options.color,
                fontWeight: 'bold',
              }"
            >
              {{ element.options.defaultValue }}
            </h2>
          </a-col>
        </a-row>
      </template>

      <template v-if="element.type === 'grid'">
        <a-row
          type="flex"
          v-if="element.key"
          :key="element.key"
          :class="{ active: selectWidget?.key === element.key }"
          :gutter="0"
          :justify="element.options.justify"
          :align="element.options.align"
        >
          <a-col v-for="(col, colIndex) of element.layout" :key="colIndex" :span="24">
            <Draggable
              class="widget-col-list"
              item-key="key"
              ghostClass="ghost"
              handle=".drag-widget"
              :animation="200"
              :group="{ name: 'people' }"
              :no-transition-on-drag="true"
              :list="col.list"
              @add="handleColMoveAdd($event, col.list, element)"
            >
              <template #item="{ element: childElement, index: itemIndex }">
                <div>
                  <AntdWidgetFormItem
                    v-if="childElement.key"
                    :key="childElement.key"
                    :element="childElement"
                    class="drag-widget"
                    :config="config"
                    :level="level! + 1"
                    :selectWidget="selectWidget"
                    @click.stop="handleItemClick(childElement)"
                    @delete="handleDeleteClick(col.list, itemIndex, childElement)"
                  />
                </div>
              </template>
            </Draggable>
          </a-col>
        </a-row>
      </template>

      <template v-if="element.type === 'tab'">
        <a-row
          class="widget-col widget-view"
          type="flex"
          v-if="element.key"
          :key="element.key"
          :class="{ active: selectWidget?.key === element.key }"
          :gutter="0"
          :justify="element.options.justify"
          :align="element.options.align"
          @click="handleItemClick(element)"
        >
          <a-tabs
            style="width: 100%"
            :type="element.options.type"
            :tab-position="element.options.tabPosition"
            default-active-key="0"
          >
            <a-tab-pane v-for="(col, colIndex) of element.layout" :key="colIndex" :tab="col.name">
              <Draggable
                class="widget-col-list"
                item-key="key"
                ghostClass="ghost"
                handle=".drag-widget"
                :animation="200"
                :group="{ name: 'people' }"
                :no-transition-on-drag="true"
                :list="col.list"
                @add="handleColMoveAdd($event, col.list, element)"
              >
                <template #item="{ element: childElement, index: itemIndex }">
                  <div>
                    <AntdWidgetFormItem
                      v-if="childElement.key"
                      :key="childElement.key"
                      :element="childElement"
                      class="drag-widget"
                      :config="config"
                      :selectWidget="selectWidget"
                      :labelCol="config.labelCol"
                      :level="level! + 1"
                      @click.stop="handleItemClick(childElement)"
                      @delete="handleDeleteClick(col.list, itemIndex, childElement)"
                    />
                  </div>
                </template>
              </Draggable>
            </a-tab-pane>
          </a-tabs>
        </a-row>
      </template>

      <template v-if="element.type === 'form'">
        <a-row
          class="widget-col mb-10px"
          type="flex"
          v-if="element.key"
          :key="element.key"
          :class="{ active: selectWidget?.key === element.key }"
          :gutter="0"
          :justify="element.options.justify"
          :align="element.options.align"
          @click="handleItemClick(element)"
        >
          <a-col :span="24" class="bg-white">
            <a-button
              v-if="element.options.useSelectButton"
              class="!absolute right-0 top-[-34px] !text-xs"
              type="primary"
              size="small"
              >{{ element.options.buttonName }}</a-button
            >
            <Draggable
              class="widget-col-list !border-none"
              item-key="key"
              ghostClass="ghost"
              handle=".drag-widget"
              :animation="200"
              :group="{ name: 'people' }"
              :no-transition-on-drag="true"
              :list="element.children"
              @add="handleColMoveAdd($event, element.children, element)"
            >
              <template #item="{ element: childElement, index: itemIndex }">
                <transition-group name="fade" tag="div">
                  <AntdWidgetFormItem
                    v-if="childElement.key"
                    :key="childElement.key"
                    :element="childElement"
                    class="drag-widget"
                    :config="config"
                    :level="level! + 1"
                    :selectWidget="selectWidget"
                    @click.stop="handleItemClick(childElement)"
                    @delete="handleDeleteClick(element.children, itemIndex, element)"
                  />
                </transition-group>
              </template>
            </Draggable>
            <div class="flex justify-end items-center border-b mb-2">
              <a-button type="error" class="mt-2 mr-2 mb-2 !text-xs !rounded-2xl" size="small"
                >删除</a-button
              >
            </div>
            <a-button type="primary" style="width: calc(100% - 16px)" class="mb-2 mx-2"
              >新增</a-button
            >
          </a-col>
        </a-row>
      </template>
      <template v-if="element.type === 'one-for-one'">
        <a-row
          class="widget-col mb-10px"
          type="flex"
          v-if="element.key"
          :key="element.key"
          :class="{ active: selectWidget?.key === element.key }"
          :gutter="0"
          :justify="element.options.justify"
          :align="element.options.align"
          @click="handleItemClick(element)"
        >
          <a-col :span="24">
            <Draggable
              class="widget-col-list"
              item-key="key"
              ghostClass="ghost"
              handle=".drag-widget"
              :animation="200"
              :group="{ name: 'people' }"
              :no-transition-on-drag="true"
              :list="element.children"
              @add="handleColMoveAdd($event, element.children, element)"
            >
              <template #item="{ element: childElement, index: itemIndex }">
                <transition-group name="fade" tag="div">
                  <AntdWidgetFormItem
                    v-if="childElement.key"
                    :key="childElement.key"
                    :element="childElement"
                    class="drag-widget"
                    :config="config"
                    :level="level! + 1"
                    :selectWidget="selectWidget"
                    @click.stop="handleItemClick(childElement)"
                    @delete="handleDeleteClick(element.children, itemIndex, element)"
                  />
                </transition-group>
              </template>
            </Draggable>
          </a-col>
        </a-row>
      </template>
      <template v-if="element.type === 'card'">
        <CollapseContainer :title="element.options.title" :bordered="false" :hasLeftBorder="true">
          <a-row
            type="flex"
            v-if="element.key"
            :key="element.key"
            :class="{ active: selectWidget?.key === element.key }"
            :gutter="0"
            :justify="element.options.justify"
            :align="element.options.align"
          >
            <a-col v-for="(col, colIndex) of element.layout" :key="colIndex" :span="24">
              <Draggable
                item-key="key"
                ghostClass="ghost"
                handle=".drag-widget"
                :animation="200"
                :group="{ name: 'people' }"
                :no-transition-on-drag="true"
                :list="col.list"
                @add="handleColMoveAdd($event, col.list, element)"
              >
                <template #item="{ element: childElement, index: itemIndex }">
                  <div>
                    <AntdWidgetFormItem
                      v-if="childElement.key"
                      :key="childElement.key"
                      :element="childElement"
                      class="drag-widget"
                      :config="config"
                      :selectWidget="selectWidget"
                      :childIndex="childIndex"
                      :level="level! + 1"
                      @click.stop="handleItemClick(childElement)"
                      @delete="handleDeleteClick(col.list, itemIndex, childElement)"
                    />
                  </div>
                </template>
              </Draggable>
            </a-col>
          </a-row>
        </CollapseContainer>
      </template>

      <template v-if="element.type === 'user'">
        <a-input
          :size="config.size"
          :value="element.options.defaultValue"
          :placeholder="element.options.placeholder"
          :disabled="element.options.disabled"
        >
          <template #prefix v-if="element.options.prefix">
            <Icon :icon="element.options.prefix" />
          </template>
          <template #suffix v-if="element.options.suffix">
            <Icon :icon="element.options.suffix" />
          </template>
        </a-input>
      </template>
      <template v-if="element.type === 'computational'">
        <Computation
          :size="config.size"
          :value="element.options.defaultValue"
          :maxlength="parseInt(element.options.maxlength)"
          :placeholder="element.options.placeholder"
          :addonBefore="element.options.addonBefore"
          :addonAfter="element.options.addonAfter"
          :disabled="element.options.disabled"
          :readonly="element.options.readonly"
          :prefix="element.options.prefix"
        />
      </template>

      <template v-if="element.type === 'money-chinese'">
        <MoneyChineseInput
          :size="config.size"
          :value="element.options.defaultValue"
          :maxlength="parseInt(element.options.maxlength)"
          :placeholder="element.options.placeholder"
          :addonBefore="element.options.addonBefore"
          :addonAfter="element.options.addonAfter"
          :disabled="element.options.disabled"
          :prefix="element.options.prefix"
          :suffix="element.options.suffix"
        />
      </template>
      <template v-if="element.type === 'info'">
        <CommonInfo
          :size="config.size"
          :placeholder="element.options.placeholder"
          :infoType="element.options.infoType"
          disabled
        />
      </template>
      <template v-if="element.type === 'organization'">
        <SelectDepartment
          :size="config.size"
          :value="element.options.defaultValue"
          :placeholder="element.options.placeholder"
          :disabled="element.options.disabled"
        />
      </template>
      <template v-if="element.type === 'map'">
        <SelectMap
          :size="config.size"
          :value="element.options.defaultValue"
          :placeholder="element.options.placeholder"
          :disabled="element.options.disabled"
          :prefix="element.options.prefix"
          :suffix="element.options.suffix"
          :address="element.options.address"
          :latiAndLong="element.options.latiAndLong"
          :tableIndex="childIndex"
          :mainKey="element.bindTable"
        />
      </template>
      <template v-if="element.type === 'qrcode'">
        <XjrQrcode
          :defaultValue="element.options.defaultValue"
          :disabled="element.options.disabled"
          :apiConfig="element.options.apiConfig"
          :codeType="element.options.codeType"
        />
      </template>
    </a-form-item>
    <div
      class="widget-view-action"
      :class="{
        'widget-col-action': element.type === 'grid',
      }"
      :style="{ right: -(50 + level! * 10) + 'px' }"
      v-if="
        selectWidget?.key === element.key && element.type != 'form' && element.type != 'one-for-one'
      "
    >
      <span class="svgicon icon-delete">
        <SvgIcon name="delete" @click.stop="$emit('delete')" />
      </span>
    </div>
    <div
      class="widget-view-drag"
      :class="{
        'widget-col-action': element.type === 'grid',
      }"
      :style="{ right: -(50 + level! * 10) + 'px' }"
      v-if="selectWidget?.key === element.key"
    >
      <span class="svgicon icon-move">
        <SvgIcon name="move" className="drag-widget" />
      </span>
    </div>
  </div>
</template>

<script lang="ts">
  import { defineComponent, inject, PropType, computed, watch, Ref } from 'vue';
  import { SvgIcon, Icon } from '/@/components/Icon';
  import { RichTextEditor } from '/@/components/RichTextEditor/index';
  import AutoCodeRule from '/@/components/Form/src/components/AutoCodeRule.vue';
  import ApiSelect from '/@/components/Select/src/Select.vue';
  import ApiCascader from '/@/components/Form/src/components/ApiCascader.vue';
  import { XjrSwitch } from '/@/components/Switch';
  import { ColorPicker } from '/@/components/ColorPicker';
  import { Computation } from '/@/components/Computation';
  import { CollapseContainer } from '/@/components/Container';
  import { AssociateSelect } from '/@/components/AssociateSelect';
  import ApiRadioGroup from '/@/components/Form/src/components/ApiRadioGroup.vue';
  import ApiCheckboxGroup from '/@/components/Form/src/components/ApiCheckboxGroup.vue';
  import SelectArea from '/@/components/Form/src/components/SelectArea.vue';
  import CommonInfo from '/@/components/Form/src/components/CommonInfo.vue';
  import SelectDepartment from '/@/components/Form/src/components/SelectDepartment.vue';
  import SelectMap from '/@/components/Form/src/components/SelectMap.vue';
  import XjrQrcode from '/@/components/Form/src/components/QrCode.vue';
  import MoneyChineseInput from '/@/components/Form/src/components/MoneyChineseInput.vue';
  import { TimePicker } from '/@/components/TimePicker';
  import { XjrDatePicker } from '/@/components/DatePicker';
  import { PlusOutlined } from '@ant-design/icons-vue';
  import {
    WidgetForm,
    noHaveTitle,
    noHaveField,
    noHaveTableAndField,
    subFormUnUseComponents,
    oneForOneUnUseComponents,
  } from '/@/components/Designer/src/types';
  import Draggable from 'vuedraggable';
  import { buildUUID } from '/@/utils/uuid';
  import { changeToPinyin, checkTabCanDelete } from '/@/utils/event/design';
  import { random } from 'lodash-es';
  import { getAppEnvConfig } from '/@/utils/env';
  import { getToken } from '/@/utils/auth';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { useI18n } from '/@/hooks/web/useI18n';
  const { t } = useI18n();
  export default defineComponent({
    name: 'AntdWidgetFormItem',
    components: {
      SvgIcon,
      RichTextEditor,
      Draggable,
      Icon,
      AutoCodeRule,
      ApiSelect,
      ApiCascader,
      AssociateSelect,
      ApiRadioGroup,
      ApiCheckboxGroup,
      SelectArea,
      CommonInfo,
      SelectDepartment,
      MoneyChineseInput,
      XjrSwitch,
      ColorPicker,
      Computation,
      TimePicker,
      XjrDatePicker,
      SelectMap,
      XjrQrcode,
      CollapseContainer,
      PlusOutlined,
    },
    props: {
      config: {
        type: Object as PropType<WidgetForm['config']>,
        required: true,
      },
      element: {
        type: Object,
        required: true,
      },
      selectWidget: {
        type: Object,
      },
      labelCol: {
        type: Object,
        default: () => {},
      },
      childIndex: {
        type: Number,
      },
      level: {
        type: Number,
        default: () => 0,
      },
    },
    emits: ['copy', 'delete', 'update:widgetFormSelect'],
    setup(props) {
      const { notification } = useMessage();

      const handleFilterOption = (input: string, option) => {
        const label = option.label || option.name;
        return label.toLowerCase().includes(input.toLowerCase());
      };

      const widgetForm = inject('widgetForm') as any;

      //一对一组件是否包含无法使用的组件
      const oneForOneIsHaveUnUseComp = (compList: any[], isChild = false): boolean => {
        for (let item of compList) {
          //如果当前遍历到的组件是一对一
          if (item.type === 'one-for-one') {
            //判断一对一组件下面
            const result = oneForOneIsHaveUnUseComp(item.children, true);
            if (result) return true;
          }
          if (item.type === 'tab' || item.type === 'card' || item.type === 'grid') {
            for (const child of item.layout) {
              const result = oneForOneIsHaveUnUseComp(child.list, isChild);
              if (result) return true;
            }
          }
          //如果遍历的是one-for-one 组件里面的子组件 就需要判断是否包含不允许使用的组件
          if (isChild && oneForOneUnUseComponents.includes(item.type)) {
            return true;
          }
        }
        return false;
      };

      const handleColMoveAdd = (event: any, list: any, parent: any = null) => {
        const { newIndex } = event;

        if (oneForOneIsHaveUnUseComp(widgetForm.value.list)) {
          list.splice(newIndex, 1);
          customNotifiy('单表组件无法使用子表单组件 以及 单表组件！');
          return;
        }

        //如果parent参数不为空 就是子表单添加事件 如果是上级未绑定表不允许添加子组件
        if (
          parent &&
          (parent.type === 'form' || parent.type === 'one-for-one') &&
          !parent.bindTable
        ) {
          list.splice(newIndex, 1);
          customNotifiy(
            parent.type === 'form'
              ? '子表单组件未绑定表，不允许添加子组件'
              : '单表组件未绑定表，不允许添加子组件',
          );
          return;
        }
        //如果parent参数不为空 就是子表单添加事件 判断是否为子表单不允许的组件
        if (
          parent &&
          parent.type === 'form' &&
          subFormUnUseComponents.includes(list[newIndex].type)
        ) {
          list.splice(newIndex, 1);
          customNotifiy('子表单组件不允许使用此类组件');
          return;
        }

        //如果parent参数不为空 就是子表单添加事件 判断是否为子表单不允许的组件
        if (
          parent &&
          parent.type === 'one-for-one' &&
          oneForOneUnUseComponents.includes(list[newIndex].type)
        ) {
          list.splice(newIndex, 1);
          customNotifiy('单表组件无法使用子表单组件 以及 单表组件！');
          return;
        }

        //递归向最上级查 如果最上级是单表组件 所有下级组件不允许使用 表格组件 与  单表组件
        if (parent && parent.hasOwnProperty('children')) {
        }

        if (parent && parent.type === 'form' && parent.bindTable) {
          //如果parent参数不为空 就是子表单添加事件  并且已经绑定过表  所有子组件也默认绑定
          list[newIndex].bindTable = parent.bindTable;
        }

        //如果parent参数不为空 就是子表单添加事件  并且已经绑定过表  所有子组件也默认绑定
        if (parent && parent.type === 'one-for-one' && parent.bindTable) {
          list[newIndex].bindTable = parent.bindTable;
        }
        const key = buildUUID().replaceAll('-', '');
        list[newIndex] = JSON.parse(JSON.stringify(list[newIndex]));
        list[newIndex].key = key;
        //如果是父级是 子表单组件 默认把下级组件 都加上标识
        if (parent && (parent.type === 'form' || parent.type === 'one-for-one')) {
          list[newIndex].isSubFormChild = true;
        } else {
          //从子表拖入布局组件时
          list[newIndex].isSubFormChild = false;
        }

        //判断是否是栅格布局内组件
        list[newIndex].isGridChild = parent && parent.type === 'grid';
        let bindTable = '';
        if (['tab', 'grid', 'card'].includes(parent.type)) {
          bindTable = parent.bindTable;
        }
        addBindTableAndField(list[newIndex], bindTable);
      };

      let state = inject('state') as any;
      const designType = inject<Ref<string>>('designType');
      let mainTableName;
      if (designType?.value !== 'data') {
        mainTableName = inject<string>('mainTableName');
      }

      watch(
        () => props.element.label,
        (val) => {
          if (val && designType?.value !== 'data') {
            // props.element.bindField = changeToPinyin(val) + random(1000, 9999);
          }
        },
      );

      const itemLabelCol = computed(() => {
        return props.element.options.span ? { span: props.element.options.span } : props.labelCol;
      });

      const handleItemClick = (row: any) => {
        state.widgetFormSelect = row;
      };

      const handleDeleteClick = async (list: any, index: number, element?) => {
        if (element.type == 'form') {
          customNotifiy('子表单里的组件不能删除');
          return;
        } else if (element.type == 'one-for-one') {
          customNotifiy('单表组件里的组件不能删除');
          return;
        } else if (element.type == 'tab' || element.type == 'card' || element.type == 'grid') {
          let str =
            element.type == 'tab' ? '选项卡' : element.type == 'card' ? '卡片布局' : '栅格布局';
          if (checkTabCanDelete(element.layout) > 0) {
            notification.error({
              message: t('提示'),
              description: t(str + '下有不能删除的组件，所以不能删除此' + str),
            });
            return;
          }
        } else if (element.options.required) {
          customNotifiy('必填的组件不能删除');
          return;
        }
        await deleteAdoptedCalc(index, list);
        list.splice(index, 1);
      };

      function customNotifiy(str) {
        notification.error({
          message: t('提示'),
          description: t(str),
        });
      }
      const addBindTableAndField = (component: any, bindTable?) => {
        //非代码优先、需要绑定字段、组件没有绑定字段的情况下新增绑定字段
        if (designType?.value !== 'data') {
          const rangeComponents = ['time-range', 'date-range'];
          if (rangeComponents.includes(component.type)) {
            component.bindStartTime = changeToPinyin(component.label) + random(1000, 9999);
            component.bindEndTime = changeToPinyin(component.label) + random(1000, 9999);
          } else if (!noHaveField.includes(component.type) && !component.bindField) {
            component.bindField = changeToPinyin(component.label) + random(1000, 9999);
          }

          if (!noHaveTableAndField.includes(component.type) && !component.isSubFormChild) {
            if (component.type === 'form' || component.type === 'one-for-one') {
              //布局组件里有子表
              component.bindTable = `${mainTableName.value}_child_${random(1000, 9999)}`;
            } else {
              //布局组件内的组件
              component.bindTable = bindTable ? bindTable : mainTableName.value;
            }
          }
        }
        if (component.isGridChild) component.options.span = 7;
      };

      //删除引用已删除的财务组件的计算式配置
      const deleteAdoptedCalc = (index: number, list: any[]) => {
        const component = list[index];
        if (['computational', 'money-chinese'].includes(component.type)) {
          component.options.beAdoptedComponent?.map((key) => {
            getLayoutComponent(state.widgetForm.list, key);
          });
        }
      };

      const getLayoutComponent = (list, key) => {
        list?.map((item) => {
          if (['tab', 'grid', 'card'].includes(item.type)) {
            for (const child of item.layout!) {
              getLayoutComponent(child.list, key);
            }
          } else if (item.type === 'form') {
            item.children.map((child: any) => {
              if (['computational', 'money-chinese'].includes(child.type) && child.key === key) {
                child.options.computationalConfig = [];
                child.options.computationalConfigValue = '== 请填写计算式配置 ==';
              }
            });
          } else {
            if (['computational', 'money-chinese'].includes(item.type) && item.key === key) {
              item.options.computationalConfig = [];
              item.options.computationalConfigValue = '== 请填写计算式配置 ==';
            }
          }
        });
      };

      return {
        itemLabelCol,
        handleItemClick,
        handleDeleteClick,
        handleFilterOption,
        noHaveTitle,
        handleColMoveAdd,
        addBindTableAndField,
        deleteAdoptedCalc,
        getAppEnvConfig,
        getToken,
        t,
      };
    },
  });
</script>
<style scoped lang="less">
  :deep(.ant-tabs) {
    overflow: visible;
  }

  .ant-form-item.active {
    & > .vben-collapse-container {
      background: #eef4ff;
    }
  }

  .widget-item-container .widget-view {
    padding: 10px;
    cursor: pointer;
    margin-bottom: 0;
  }

  .widget-item-container > div.active {
    background: #eef4ff;
  }

  .widget-item-container {
    position: relative;
  }

  .widget-view-action {
    position: absolute;
    top: 0;
  }

  .widget-view-drag {
    position: absolute;
    top: 30px;
  }

  .svgicon {
    color: #0960bd;
    border: 1px solid #0960bd;
    border-radius: 50%;
    width: 24px;
    height: 24px;
    line-height: 20px;
    display: inline-block;
    text-align: center;
    cursor: pointer;
    margin-left: 10px;
  }

  .svgicon svg {
    width: 12px !important;
    height: 12px !important;
  }

  .icon-delete {
    border: 1px solid #f64c4c;
    color: #f64c4c;
  }

  .icon-move {
    border: 1px solid #90b665;
    color: #90b665;
  }

  .radio-default {
    display: inline-block !important;
  }

  .radio-button {
    flex-wrap: wrap;
  }

  :deep(.ant-form-item-control-input-content .ant-radio-group .ant-radio-button-wrapper) {
    padding: 3px 7px !important;
    flex: auto;
  }

  :deep(.ant-form-item-label > label) {
    white-space: normal;
    display: inline;
    line-height: 28px;
    cursor: pointer;
  }

  .fc-style .widget-form-container .widget-form-list .widget-col.active {
    border: 1px dashed #e6a23c !important;
  }

  .fc-style .widget-form-container .widget-form-list .widget-col:hover {
    background: #fdf6ec;
    outline: 1px dashed #e6a23c;
    outline-offset: 0;
  }

  .fc-style .widget-form-container .widget-form-list .widget-col-list {
    min-height: 100px;
    border: 1px dashed #ccc;
    background: #fff;
  }

  /* @import '/@/assets/style/designer/index.css'; */
</style>
